// 存放图书API
use axum::{
    http::StatusCode,
    http::{HeaderMap, Request},
    middleware::Next,
    response::Response,
    routing::{get, post},
    Router,
};
use axum_csrf::{CsrfConfig, CsrfLayer};
use axum_session::{ReadOnlySession, SessionLayer, SessionRedisPool, SessionStore};
use serde::Deserialize;
use tower::ServiceBuilder;

use crate::{SharedState, UserSession, SESSION_KEY};

pub mod book;
pub mod login;
pub mod user;

/// 前端路由
pub fn router(
    shared_state: SharedState,
    session_store: SessionStore<SessionRedisPool>,
    csrf_config: CsrfConfig,
) -> Router {
    Router::new()
        .route("/my", get(book::my_html))
        .route("/listbook", get(book::list_book_html))
        .route("/login", get(login::login_html).post(login::login_action))
        .route(
            "/addbook",
            get(book::add_book_html).post(book::add_book_action),
        )
        .route("/detailbook/:id", get(book::detail_book_html))
        .route("/sharebook/:id", post(book::share_book_action))
        .route("/delbook/:id", post(book::delete_book_action))
        .route("/chatbook/:name", get(book::chat_book_html))
        .route("/chat2book", get(book::chat2_book_html))
        .route("/wsbook", get(book::chat_book_websocket))
        .with_state(shared_state)
        .layer(
            ServiceBuilder::new()
                .layer(SessionLayer::new(session_store))
                .layer(axum::middleware::from_fn(session_auth))
                .layer(CsrfLayer::new(csrf_config)),
        )
}

async fn session_auth<B>(
    session: ReadOnlySession<SessionRedisPool>,
    request: Request<B>,
    next: Next<B>,
) -> Result<Response, (StatusCode, HeaderMap, ())> {
    {
        let url = request.uri();
        let limit_url =
            "/my,/listbook,/addbook,/sharebook,/delbook,/detailbook,/chatbook,/wsbook,/chat2book";
        let url_path = url.path();
        let check_path: Vec<&str> = url_path.split('/').collect();
        tracing::debug!("check_path:{:?}", check_path);
        let ok = limit_url.contains(check_path[1]);
        tracing::debug!("path {},check url {}", url.path(), ok);
        if ok {
            let rabbit_session = session.get(SESSION_KEY).unwrap_or(UserSession::default());
            if rabbit_session.openid == "" {
                let mut headers = HeaderMap::new();
                headers.insert(axum::http::header::LOCATION, "/login".parse().unwrap());
                return Err((StatusCode::FOUND, headers, ()));
            }
        }
    }

    let response = next.run(request).await;

    // do something with `response`...

    Ok(response)
}

#[derive(Debug, Deserialize)]
pub struct EcodeParams {
    ecode: Option<i32>,
}
// code 表达的含义
// 10000 正确的，无错误
// 19999 未知错误
// 10001 vcode参数为空
// 10002 vcode参数值无效
// 10003 图书名称参数为空
// 10004 出版社参数为空
// 10005 ISBN参数为空
// 10006 Token无效
// 10007 重复提交
// 10008 图书未审核
